#include "dxdiag_res.h"
#include "dxdiagcom.h"
#include "wine/debug.h"
#include "wine/unicode.h"

static const WCHAR strName[] = {'N','a','m','e','\0'};
static const WCHAR strVersion[] = {'V','e','r','s','i','o','n','\0'};
static const WCHAR strLanguage[] = {'L','a','n','g','u','a','g','e','\0'};
static const WCHAR strDate[] = {'D','a','t','e','\0'};
static const WCHAR strSize[] = {'S','i','z','e','\0'};

WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);

/* Files tab callback proceedure */
LRESULT CALLBACK Files_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    HBRUSH g_hbrBackground = CreateSolidBrush(RGB(255,255,255));
    switch(uMsg) {
        case WM_INITDIALOG:
            return TRUE;
                break;
        case WM_CTLCOLORSTATIC:
            if (GetDlgCtrlID((HWND) lParam) == FILESTAB_NOTESEDIT) {
                return (LRESULT)g_hbrBackground;
                     break;
            }
         default:
            break;
    }

    return FALSE;
}

BOOL FilesInfo_GetInfo(DxDiagCOM* pcom, FilesInfo* info) {
    IDxDiagContainer* files;
    IDxDiagContainer* file;
    WCHAR buf[BUF_SIZE];
    WCHAR query[BUF_SIZE];
    HRESULT hr;
    UINT i;

    static const WCHAR DxDiag_DirectXFiles[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','X','F','i','l','e','s','\0'};
    static const WCHAR szDXFileNotesEnglish[] = {'s','z','D','X','F','i','l','e','N','o','t','e','s','E','n','g','l','i','s','h','\0'};
    static const WCHAR szName[] = {'s','z','N','a','m','e','\0'};
    static const WCHAR szVersion[] = {'s','z','V','e','r','s','i','o','n','\0'};
    static const WCHAR szAttributes[] = {'s','z','A','t','t','r','i','b','u','t','e','s','\0'};
    static const WCHAR szLanguageLocalized[] = {'s','z','L','a','n','g','u','a','g','e','L','o','c','a','l','i','z','e','d','\0'};
    static const WCHAR szDatestampLocalized[] = {'s','z','D','a','t','e','s','t','a','m','p','L','o','c','a','l','i','z','e','d','\0'};
    static const WCHAR lNumBytes[] = {'l','N','u','m','B','y','t','e','s','\0'};
    static const WCHAR formatStr[] = {'%','0','.','1','f',' ','k','B','\0'};

    /* Get the files container */

    if (FAILED(DxDiagCOM_GetContainer(pcom->root, DxDiag_DirectXFiles, &files)))
        return FALSE;

    /* Get notes */

    DxDiagCOM_GetStringProperty(files, szDXFileNotesEnglish, &info->notes);


    /* Allocate space */
    hr = IDxDiagContainer_GetNumberOfChildContainers(files, &info->numFiles);
    if (FAILED(hr))
    {
        WINE_ERR("IDxContainer_GetNumberOfChildContainers failed\n");
        return FALSE;
    }
    info->files = HeapAlloc(GetProcessHeap(), 0, sizeof(FileInfo)*info->numFiles);

    for (i = 0; i < info->numFiles; i++)
    {
        /* Get the name of the current file container */
        hr = IDxDiagContainer_EnumChildContainerNames(files, i, query, BUF_SIZE);
        /* Get the file container */
        IDxDiagContainer_GetChildContainer(files, query, &file);

        /* Get properties */
        DxDiagCOM_GetStringProperty(file, szName, &info->files[i].name);
        DxDiagCOM_GetStringProperty(file, szVersion, &info->files[i].version);
        DxDiagCOM_GetStringProperty(file, szAttributes, &info->files[i].attributes);
        DxDiagCOM_GetStringProperty(file, szLanguageLocalized, &info->files[i].language);
        DxDiagCOM_GetStringProperty(file, szDatestampLocalized, &info->files[i].date);
        DxDiagCOM_GetIntegerProperty(file, lNumBytes, &info->files[i].size);

        wsprintfW(buf, formatStr, (float)info->files[i].size / 1000.0f);
        info->files[i].sizeStr = malloc(sizeof(WCHAR) * lstrlenW((LPCWSTR)buf));
        lstrcpyW(info->files[i].sizeStr,(LPCWSTR)buf);
    }
    return TRUE;
}

void Files_DisplayData()
{
    LVCOLUMNW lvc;
    LVITEMW lvi;
    UINT i;
    WCHAR buf[BUF_SIZE];
    HWND hList = GetDlgItem(hTabDisplay, FILESTAB_FILESLIST);
    static const WCHAR strAttributes[] = {'A','t','t','r','i','b','u','t','e','s','\0'};

    /* Add columns */
    lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
    lvc.fmt = LVCFMT_LEFT;
    lvc.cx = 100;
    lvc.iSubItem = 0;

    lstrcpyW(buf, strName);
    lvc.pszText = buf;
    ListView_InsertColumnW(hList, 0, &lvc);
    lstrcpyW(buf, strVersion);
    lvc.pszText = buf;
    ListView_InsertColumnW(hList, 1, &lvc);
    lstrcpyW(buf, strAttributes);
    lvc.pszText = buf;
    ListView_InsertColumnW(hList, 2, &lvc);
    lstrcpyW(buf, strLanguage);
    lvc.pszText = buf;
    ListView_InsertColumnW(hList, 3, &lvc);
    lstrcpyW(buf, strDate);
    lvc.pszText = buf;
    ListView_InsertColumnW(hList, 4, &lvc);
    lstrcpyW(buf, strSize);
    lvc.pszText = buf;
    ListView_InsertColumnW(hList, 5, &lvc);

    /* Add items */
    lvi.mask = LVIF_TEXT;
    lvi.state = 0;
    lvi.stateMask = 0;

    for (i = 0; i < filesInfo.numFiles; i++)
    {
        lvi.iItem = i;
        lvi.iSubItem = 0;
        lvi.lParam = (LPARAM) &filesInfo.files[i];
        lvi.pszText = LPSTR_TEXTCALLBACKW;
        ListView_InsertItemW(hList, &lvi);

        ListView_SetItemTextW(hList,i,0,filesInfo.files[i].name);
        ListView_SetItemTextW(hList,i,1,filesInfo.files[i].version);
        ListView_SetItemTextW(hList,i,2,filesInfo.files[i].attributes);
        ListView_SetItemTextW(hList,i,3,filesInfo.files[i].language);
        ListView_SetItemTextW(hList,i,4,filesInfo.files[i].date);
        ListView_SetItemTextW(hList,i,5,filesInfo.files[i].sizeStr);
    }

     /* Display the notes */
     hList = GetDlgItem(hTabDisplay, FILESTAB_NOTESEDIT);
     SendMessageW(hList, WM_SETTEXT, 0, (LPARAM)filesInfo.notes);
}

void Files_SaveText(FILE* pFile)
{
    /* XXX fixme: not implemented */
}

void Files_SaveXML(XML_Node* node)
{
    UINT i;
    XML_Node* fileXML;
    static const WCHAR strFile[] = {'F','i','l','e','\0'};
    static const WCHAR strBeta[] = {'B','e','t','a','\0'};
    static const WCHAR strDebug[] = {'D','e','b','u','g','\0'};
    static const WCHAR strExists[] = {'E','x','i','s','t','s','\0'};
    static const WCHAR strProblem[] = {'P','r','o','b','l','e','m','\0'};

    for (i = 0; i < filesInfo.numFiles; i++)
    {
        fileXML = XML_insertChildNode(node, strFile, NULL);
        XML_insertChildNode(fileXML, strName, filesInfo.files[i].name);
        XML_insertChildNode(fileXML, strVersion, filesInfo.files[i].version);
        XML_insertChildNode(fileXML, strLanguage, filesInfo.files[i].language);
        XML_insertChildNode(fileXML, strBeta, NULL);
        XML_insertChildNode(fileXML, strDebug, NULL);
        XML_insertChildNode(fileXML, strDate, filesInfo.files[i].date);
        XML_insertChildNode(fileXML, strSize, filesInfo.files[i].sizeStr);
        XML_insertChildNode(fileXML, strExists, NULL);
        XML_insertChildNode(fileXML, strProblem, NULL);
    }

}
